package com.starry.module.system.core.tenant.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.starry.core.common.constants.CommonError;
import com.starry.core.common.domain.vo.PageVo;
import com.starry.core.common.execption.ServiceException;
import com.starry.db.core.enums.DBEnableDisableStatusEnum;
import com.starry.db.core.query.LambdaQueryWrapperX;
import com.starry.module.system.api.tenant.domain.qo.SysTenantPackagePageQo;
import com.starry.module.system.api.tenant.domain.qo.SysTenantPackageQo;
import com.starry.module.system.api.tenant.domain.vo.SysTenantPackageDtlVo;
import com.starry.module.system.api.tenant.domain.vo.SysTenantPackageVo;
import com.starry.module.system.core.menu.service.SysMenuService;
import com.starry.module.system.core.tenant.entity.SysTenantPackage;
import com.starry.module.system.core.tenant.mapper.SysTenantPackageMapper;
import com.starry.module.system.core.tenant.service.SysTenantPackageService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 系统租户套餐-服务实现
 *
 * @author xiaoke
 */
@Service("sysTenantPackageService")
public class SysTenantPackageServiceImpl implements SysTenantPackageService {

    private final SysTenantPackageMapper sysTenantPackageMapper;
    private final SysMenuService sysMenuService;

    public SysTenantPackageServiceImpl(SysTenantPackageMapper sysTenantPackageMapper, SysMenuService sysMenuService) {
        this.sysTenantPackageMapper = sysTenantPackageMapper;
        this.sysMenuService = sysMenuService;
    }

    @Override
    public PageVo<SysTenantPackageVo> page(SysTenantPackagePageQo pageQo) {
        PageVo<SysTenantPackage> page = sysTenantPackageMapper.selectPage(pageQo);
        List<SysTenantPackageVo> vos = BeanUtil.copyToList(page.getRows(), SysTenantPackageVo.class);
        return new PageVo<>(vos, page.getTotal());
    }

    @Override
    public SysTenantPackageDtlVo getById(Long id) {
        SysTenantPackage sysTenantPackage = sysTenantPackageMapper.selectById(id);
        if (sysTenantPackage == null) {
            throw new ServiceException(CommonError.DATA_NOT_EXISTS.getMsg());
        }
        return BeanUtil.toBean(sysTenantPackage, SysTenantPackageDtlVo.class);
    }

    @Transactional
    @Override
    public Long save(SysTenantPackageQo sysTenantPackageQo) {
        LambdaQueryWrapperX<SysTenantPackage> wrapper = new LambdaQueryWrapperX<>();
        wrapper
                .eq(SysTenantPackage::getName, sysTenantPackageQo.getName());
        if (sysTenantPackageMapper.selectCount(wrapper) > 0) {
            throw new ServiceException(CommonError.DATA_EXISTS.getMsg());
        }

        //校验
        validate(sysTenantPackageQo);

        SysTenantPackage sysTenantPackage = BeanUtil.toBean(sysTenantPackageQo, SysTenantPackage.class);
        sysTenantPackage.setId(null);
        sysTenantPackageMapper.insert(sysTenantPackage);
        return sysTenantPackage.getId();
    }

    @Override
    public Set<Long> getTenantPackageMenuIds(Long id) {
        SysTenantPackageDtlVo tenantPackage = getById(id);
        if (tenantPackage.getMenuIds().isEmpty()) return Set.of();
        return tenantPackage.getMenuIds();
    }

    @Override
    public boolean existTenantPackage(Long tenantPackageId) {
        return sysTenantPackageMapper.selectCount(SysTenantPackage::getId, tenantPackageId) > 0;
    }

    @Transactional
    @Override
    public void updateById(SysTenantPackageQo sysTenantPackageQo) {
        if (sysTenantPackageQo.getId() == null) {
            throw new ServiceException(CommonError.DATA_NOT_EXISTS.getMsg());
        }

        LambdaQueryWrapperX<SysTenantPackage> wrapper = new LambdaQueryWrapperX<>();
        wrapper
                .ne(SysTenantPackage::getId, sysTenantPackageQo.getId())
                .and(w ->
                        w.eq(SysTenantPackage::getName, sysTenantPackageQo.getName())
                );
        if (sysTenantPackageMapper.selectCount(wrapper) > 0) {
            throw new ServiceException(CommonError.DATA_EXISTS.getMsg());
        }

        //校验
        validate(sysTenantPackageQo);

        SysTenantPackage sysTenantPackage = sysTenantPackageMapper.selectById(sysTenantPackageQo.getId());
        if (sysTenantPackage == null) {
            throw new ServiceException(CommonError.DATA_NOT_EXISTS.getMsg());
        }
        BeanUtil.copyProperties(sysTenantPackageQo, sysTenantPackage);
        sysTenantPackageMapper.updateById(sysTenantPackage);
    }

    @Transactional
    @Override
    public void removeByIds(Set<Long> idList) {
        if (idList.isEmpty()) return;
        sysTenantPackageMapper.deleteByIds(idList);
    }

    @Transactional
    @Override
    public void enable(Set<Long> idList) {
        if (idList.isEmpty()) return;
        sysTenantPackageMapper.updateBatch(setsysTenantPackageStatus(idList, DBEnableDisableStatusEnum.ENABLE));
    }

    @Transactional
    @Override
    public void disable(Set<Long> idList) {
        if (idList.isEmpty()) return;
        sysTenantPackageMapper.updateBatch(setsysTenantPackageStatus(idList, DBEnableDisableStatusEnum.DISABLE));
    }

    @Override
    public List<SysTenantPackageVo> list(SysTenantPackagePageQo pageQo) {
        return BeanUtil.copyToList(sysTenantPackageMapper.selectList(pageQo), SysTenantPackageVo.class);
    }

    /**
     * 校验菜单是否存在
     *
     * @param sysTenantPackageQo 菜单编号集合
     */
    private void validate(SysTenantPackageQo sysTenantPackageQo) {
        if (!sysMenuService.existMenuList(sysTenantPackageQo.getMenuIds())) {
            throw new ServiceException("菜单编号不存在");
        }
    }

    private Set<SysTenantPackage> setsysTenantPackageStatus(Set<Long> idList, DBEnableDisableStatusEnum status) {
        Set<SysTenantPackage> sysTenantPackages = new HashSet<>();
        idList.forEach(item -> {
            SysTenantPackage sysTenantPackage = new SysTenantPackage();
            sysTenantPackage.setId(item);
            sysTenantPackage.setStatus(status.getCode());
            sysTenantPackages.add(sysTenantPackage);
        });
        return sysTenantPackages;
    }


}

